package com.example.hc08test;

import android.Manifest;
import android.bluetooth.BluetoothDevice;
import android.content.Intent;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.util.Log;
import android.view.View;
import android.widget.TextView;
import android.widget.Toast;

import com.inuker.bluetooth.library.BluetoothClient;
import com.inuker.bluetooth.library.Constants;
import com.inuker.bluetooth.library.connect.listener.BleConnectStatusListener;
import com.inuker.bluetooth.library.connect.listener.BluetoothStateListener;
import com.inuker.bluetooth.library.connect.options.BleConnectOptions;
import com.inuker.bluetooth.library.connect.response.BleConnectResponse;
import com.inuker.bluetooth.library.connect.response.BleNotifyResponse;
import com.inuker.bluetooth.library.connect.response.BleWriteResponse;
import com.inuker.bluetooth.library.model.BleGattCharacter;
import com.inuker.bluetooth.library.model.BleGattProfile;
import com.inuker.bluetooth.library.model.BleGattService;
import com.inuker.bluetooth.library.search.SearchRequest;
import com.inuker.bluetooth.library.search.SearchResult;
import com.inuker.bluetooth.library.search.response.SearchResponse;
import com.inuker.bluetooth.library.utils.BluetoothLog;
import com.inuker.bluetooth.library.utils.BluetoothUtils;

import java.util.ArrayList;
import java.util.List;
import java.util.UUID;

import static com.inuker.bluetooth.library.Constants.REQUEST_SUCCESS;
import static com.inuker.bluetooth.library.Constants.STATUS_CONNECTED;

public class MainActivity extends PemissionActivity {
    private TextView mTvTitle;

    /*设备列表*/
    private List<SearchResult> mDevices;

    /**
     * 是否连接
     */
    private boolean mConnected;
    /*蓝牙设备*/
    private BluetoothDevice mDevice;
    UUID serviceUuid, characterUuid;
    BluetoothClient mClient;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        mTvTitle = (TextView) findViewById(R.id.title);
        mTvTitle.setText(R.string.string_refreshing);
        mClient = new BluetoothClient(this);
        mDevices = new ArrayList<SearchResult>();
//        1、请求蓝牙相关权限
        requestBlePermission();

        ClientManager.getClient().registerBluetoothStateListener(new BluetoothStateListener() {
            @Override
            public void onBluetoothStateChanged(boolean openOrClosed) {
                BluetoothLog.v(String.format("onBluetoothStateChanged %b", openOrClosed));
            }
        });
    }

    private void requestBlePermission() {
        requestPermission(new String[]{Manifest.permission.BLUETOOTH_ADMIN,
                        Manifest.permission.ACCESS_COARSE_LOCATION},
                "请求蓝牙相关权限", new PemissionActivity.GrantedResult() {
                    @Override
                    public void onResult(boolean granted) {
                        if (granted) {
                            //2、初始化蓝牙
                            searchDevice();
                        } else {
                            finish();
                        }
                    }
                });
    }

    private void searchDevice() {
        SearchRequest request = new SearchRequest.Builder()
                .searchBluetoothLeDevice(5000, 2)

                .build();

        ClientManager.getClient().search(request, mSearchResponse);
    }


    private final SearchResponse mSearchResponse = new SearchResponse() {
        @Override
        public void onSearchStarted() {
            mDevices.clear();
            BluetoothLog.w("MainActivity.onSearchStarted");
            mTvTitle.setText(R.string.string_refreshing);
        }

        @Override
        public void onDeviceFounded(SearchResult device) {
            BluetoothLog.w("MainActivity.onDeviceFounded " + device.device.getAddress());
            if (!mDevices.contains(device)) {
                mDevices.add(device);
                Log.d("MainActivity", "mDevices:" + mDevices);

//                Beacon beacon = new Beacon(device.scanRecord);
//                BluetoothLog.v(String.format("beacon for %s\n%s", device.getAddress(), beacon.toString()));

//                BeaconItem beaconItem = null;
//                BeaconParser beaconParser = new BeaconParser(beaconItem);
//                int firstByte = beaconParser.readByte(); // 读取第1个字节
//                int secondByte = beaconParser.readByte(); // 读取第2个字节
//                int productId = beaconParser.readShort(); // 读取第3,4个字节
//                boolean bit1 = beaconParser.getBit(firstByte, 0); // 获取第1字节的第1bit
//                boolean bit2 = beaconParser.getBit(firstByte, 1); // 获取第1字节的第2bit
//                beaconParser.setPosition(0); // 将读取起点设置到第1字节处


            }


        }

        @Override
        public void onSearchStopped() {
            BluetoothLog.w("MainActivity.onSearchStopped");
            mTvTitle.setText(R.string.scan_over);
            for (SearchResult drive : mDevices) {
                Log.d("MainActivity", drive.getName());
                if (drive.getName().equals("HELL")) {
//                    if (item.type == DetailItem.TYPE_CHARACTER) {
//                        BluetoothLog.v(String.format("click service = %s, character = %s", item.service, item.uuid));
//                        startCharacterActivity(item.service, item.uuid);
//                    }
                    mDevice = BluetoothUtils.getRemoteDevice(drive.getAddress() + "");
                    ClientManager.getClient().registerConnectStatusListener(drive.getAddress(), mConnectStatusListener);
                    connectDeviceIfNeeded();
                }
            }

        }

        private void connectDeviceIfNeeded() {
            if (!mConnected) {
                connectDevice();
            }
        }

        @Override
        public void onSearchCanceled() {
            BluetoothLog.w("MainActivity.onSearchCanceled");


        }
    };

    @Override
    protected void onPause() {
        super.onPause();
        ClientManager.getClient().stopSearch();
    }

    private void connectDevice() {

        mTvTitle.setText(R.string.connecting);
        BleConnectOptions options = new BleConnectOptions.Builder()
                .setConnectRetry(3)
                .setConnectTimeout(20000)
                .setServiceDiscoverRetry(3)
                .setServiceDiscoverTimeout(10000)
                .build();

        ClientManager.getClient().connect(mDevice.getAddress(), options, new BleConnectResponse() {
            @Override
            public void onResponse(int code, BleGattProfile profile) {
                BluetoothLog.v(String.format("profile:\n%s", profile));


                if (code == REQUEST_SUCCESS) {
//                    setGattProfile(profile);
                    mTvTitle.setText(R.string.connected);
                    serviceUuid = profile.getServices().get(3).getUUID();
                    Log.d("CJT", "getBluetoothClient().connect  --- serviceUuid  : " + serviceUuid);
                    characterUuid = profile.getService(serviceUuid).getCharacters().get(0).getUuid();
                    Log.d("CJT", "getBluetoothClient().connect  --- characterUuid : " + characterUuid);

                    BluetoothLog.w("连接成功");
                    Toast.makeText(MainActivity.this, "连接成功", Toast.LENGTH_SHORT).show();
                    // 获取温度值
                    getTemperature(mDevice.getAddress(), serviceUuid, characterUuid);

                    // 下发数据
                    writeCmd(mDevice.getAddress(), serviceUuid, characterUuid, "finish\r\n");

                }
            }
        });
    }

    /***
     * 获取温度值并显示到界面上
     * @param address           设备地址
     * @param serviceUuid       服务UUID
     * @param characterUuid     特征UUID
     */
    private void getTemperature(String address, UUID serviceUuid, UUID characterUuid) {
        mClient.notify(address, serviceUuid, characterUuid, new BleNotifyResponse() {
            @Override
            public void onNotify(UUID service, UUID character, byte[] value) {
                String hexStr = bytesToHexString(value);
//                int beginIndex = hexStr.indexOf("2b") + 2; // 加号开始截取，并且跳过加号
//                int endIndex = hexStr.indexOf("2e") + 2;  // 小数点开始截取
//                String validTemp = hexStr.substring(beginIndex, endIndex);
//                Log.d("CJT", "valid temp = " + validTemp + ", hex2Str = " + new String(hexStringToBytes(validTemp)));
//
//                // 设置温度值
//                tempView.setAngleWithAnim(Double.valueOf(new String(hexStringToBytes(validTemp))));
                Log.d("MainActivity", hexStr);
            }

            @Override
            public void onResponse(int code) {

            }
        });
    }

    /***
     * 向设备下发指令
     * @param address           设备MAC地址
     * @param serviceUuid       服务UUID
     * @param characterUuid     特征UUID
     * @param cmd               待下发的命令
     */
    private void writeCmd(String address, UUID serviceUuid, UUID characterUuid, String cmd) {
        mClient.write(address, serviceUuid, characterUuid, cmd.getBytes(), new BleWriteResponse() {
            @Override
            public void onResponse(int code) {
                if (code == Constants.REQUEST_SUCCESS) {

                }
            }
        });
    }


    /**
     * Convert hex string to byte[]
     *
     * @param hexString the hex string
     * @return byte[]
     */
    public static byte[] hexStringToBytes(String hexString) {
        if (hexString == null || hexString.equals("")) {
            return null;
        }
        hexString = hexString.toUpperCase();
        int length = hexString.length() / 2;
        char[] hexChars = hexString.toCharArray();
        byte[] d = new byte[length];
        for (int i = 0; i < length; i++) {
            int pos = i * 2;
            d[i] = (byte) (charToByte(hexChars[pos]) << 4 | charToByte(hexChars[pos + 1]));
        }
        return d;
    }

    /**
     * Convert char to byte
     *
     * @param c char
     * @return byte
     */
    private static byte charToByte(char c) {
        return (byte) "0123456789ABCDEF".indexOf(c);
    }


    //获取属性
    public void setGattProfile(BleGattProfile profile) {
        List<DetailItem> items = new ArrayList<DetailItem>();
        List<BleGattService> services = profile.getServices();

        for (BleGattService service : services) {
            items.add(new DetailItem(DetailItem.TYPE_SERVICE, service.getUUID(), service.getUUID()));
            List<BleGattCharacter> characters = service.getCharacters();
            for (BleGattCharacter character : characters) {
                items.add(new DetailItem(DetailItem.TYPE_CHARACTER, character.getUuid(), service.getUUID()));
            }
        }
        //将得到的items传递到需要发送信息的位置。DetailItem是service和character的实体。
        //上面我们就提到过，蓝牙间的消息传递获取是根据service的character来做到的。
    }


    @Override
    protected void onDestroy() {
        ClientManager.getClient().disconnect(mDevice.getAddress());
        ClientManager.getClient().unregisterConnectStatusListener(mDevice.getAddress(), mConnectStatusListener);
        super.onDestroy();
    }

    private final BleConnectStatusListener mConnectStatusListener = new BleConnectStatusListener() {
        @Override
        public void onConnectStatusChanged(String mac, int status) {
            BluetoothLog.v(String.format("DeviceDetailActivity onConnectStatusChanged %d in %s",
                    status, Thread.currentThread().getName()));

            mConnected = (status == STATUS_CONNECTED);
            connectDeviceIfNeeded();
        }
    };

    private void connectDeviceIfNeeded() {
        if (!mConnected) {
            connectDevice();
        }
    }

    /**
     * Convert byte[] to hex string.这里我们可以将byte转换成int，然后利用Integer.toHexString(int)来转换成16进制字符串。
     *
     * @param src byte[] data
     * @return hex string
     */
    public static String bytesToHexString(byte[] src) {
        StringBuilder stringBuilder = new StringBuilder("");
        if (src == null || src.length <= 0) {
            return null;
        }
        for (int i = 0; i < src.length; i++) {
            int v = src[i] & 0xFF;
            String hv = Integer.toHexString(v);
            if (hv.length() < 2) {
                stringBuilder.append(0);
            }
            stringBuilder.append(hv);
        }
        return stringBuilder.toString();
    }


}
